//
//  HMPullDownRefreshView.swift
//  iOSWeibo12
//
//  Created by Admin on 16/9/12.
//  Copyright © 2016年 itcast. All rights reserved.
//

import UIKit

let HMPullDownRefreshViewHeight: CGFloat = 60
let HMAnimationDuration: TimeInterval = 0.25

/// 刷新控件刷新状态
enum HMPullDownRefreshViewStatus: Int {
    case Normal             // 箭头向下
    case Pulling      // 箭头向上,松手就刷新
    case Refreshing         // 正在刷新
}

class HMPullDownRefreshView: UIView {
    
    /// 下拉刷新调用的闭包
    var pullToRefreshHandler: (() -> ())?
    
    // MARK: - 属性
    /// 当前状态
    var currentStatus: HMPullDownRefreshViewStatus = .Normal {
        didSet {
            switch currentStatus {
            case .Normal:
                // 显示 箭头, 隐藏转轮
                arrowView.isHidden = false
                rotationView.isHidden = true
                
                // 修改消息为 下拉刷新
                messageLabel.text = "下拉刷新"
                
                // 清空箭头的transform
                UIView.animate(withDuration: HMAnimationDuration, animations: { 
                    self.arrowView.transform = CGAffineTransform.identity
                })
            case .Pulling:
                // 修改消息为 释放刷新
                messageLabel.text = "释放刷新"
                
                // 箭头旋转 180
                UIView.animate(withDuration: HMAnimationDuration, animations: {
                    self.arrowView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI - 0.001))
                })
            case .Refreshing:
                // 隐藏箭头,显示转轮
                arrowView.isHidden = true
                rotationView.isHidden = false
                
                // 转轮旋转起来
                let rotation = CABasicAnimation(keyPath: "transform.rotation")
                rotation.toValue = M_PI * 2
                rotation.duration = 0.5
                rotation.repeatCount = MAXFLOAT

                rotationView.layer.add(rotation, forKey: nil)
                
                // 需要显示刷新控件,需要设置 superScrollView.contentInset.top 在往下偏移刷新控件的高度
                UIView.animate(withDuration: HMAnimationDuration, animations: { 
                    self.superScrollView.contentInset.top += HMPullDownRefreshViewHeight
                })
                
                // 调用闭包,开始下拉刷新
                pullToRefreshHandler?()
            }
        }
    }
    
    /// 父控件
    var superScrollView: UIScrollView!
    
    // MARK: - 公开方法
    /// 开始刷新
    func beginRefreshing() {
        currentStatus = .Refreshing
    }
    
    // 结束刷新
    func endRefreshing() {
        if currentStatus == .Refreshing {
            currentStatus = .Normal
            
            // 移除箭头的选中动画
            rotationView.layer.removeAllAnimations()
            
            // Refreshing To Normal,让tableView往上走
            UIView.animate(withDuration: HMAnimationDuration, animations: { 
                self.superScrollView.contentInset.top -= HMPullDownRefreshViewHeight
            })
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override init(frame: CGRect) {
        // 内部来决定控件的尺寸
        let newFrame = CGRect(x: 0, y: -HMPullDownRefreshViewHeight, width: UIScreen.width, height: HMPullDownRefreshViewHeight)
        super.init(frame: newFrame)
        
//        backgroundColor = UIColor.brown
        
        setupUI()
    }
    
    private func setupUI() {
        // 添加子控件
        addSubview(arrowView)
        addSubview(rotationView)
        addSubview(messageLabel)
        
        // 刚开始隐藏转轮
        rotationView.isHidden = true
        
        // 添加约束
        arrowView.translatesAutoresizingMaskIntoConstraints = false
        rotationView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        
        // 箭头
        addConstraint(NSLayoutConstraint(item: arrowView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: -30))
        addConstraint(NSLayoutConstraint(item: arrowView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0))
        
        // 小转轮
        addConstraint(NSLayoutConstraint(item: rotationView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: arrowView, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: rotationView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: arrowView, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0))
        
        // 文字
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: arrowView, attribute: NSLayoutAttribute.trailing, multiplier: 1, constant: 10))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: arrowView, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0))
    }
    
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        
        // 判断父控件是否是能滚动的控件UIScrollView
        if let scrollView = newSuperview as? UIScrollView {
            // 父控件是能滚动的控件
            // 记录下这个控件,后续访问会使用到
            self.superScrollView = scrollView
            
            // 使用KVO监听滚动
            superScrollView.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
        }
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
//        print("superScrollView.contentOffset.y = \(superScrollView.contentOffset.y)")
        
        // 用户手指拖动的时候 在 Normal 和 Pulling 之间切换
        if superScrollView.isDragging {
            // 用户手指拖动
            if currentStatus == .Pulling && superScrollView.contentOffset.y > -124 {
                print("当前状态: \(currentStatus), 切换到Normal")
                currentStatus = .Normal
            } else if currentStatus == .Normal && superScrollView.contentOffset.y <= -124 {
                print("当前状态: \(currentStatus), 切换到Pulling")
                currentStatus = .Pulling
            }
        } else {
            // 用户松手了
            if currentStatus == .Pulling {
                // 手指松开
                // 当松手的时候,如果是Pulling状态就切换到RefReshing 正在刷新
                print("切换到Refreshing")
                currentStatus = .Refreshing
            }
        }
    }
    
    /// 在对象销毁的时候移除监听
    deinit {
        superScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    // MARK: - 懒加载
    /// 箭头
    private lazy var arrowView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //
    /// 小转轮
    private lazy var rotationView: UIImageView = UIImageView(image: UIImage(named: "tableview_loading"))
    //
    /// 文字
    private lazy var messageLabel: UILabel = {
        let label = UILabel()
        
        label.textColor = UIColor.darkGray
        label.font = UIFont.systemFont(ofSize: 14)
        label.text = "下拉刷新"
        label.sizeToFit()
        
        return label
    }()
}
